package com.tlgen.utils;

import com.alibaba.fastjson.JSONObject;
import org.yaml.snakeyaml.Yaml;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

import static com.tlgen.constant.Constant.*;
import static com.tlgen.utils.StringUtils.formatSeparator;

/**
 * yml 文件读取工具类
 */
public class YamlUtils {

    public static String APP_DEFAULT_CONFIG_PATH = "";

    static {
        String resourceAbsolutePath = ScanUtils.getResourceAbsolutePath();
        APP_DEFAULT_CONFIG_PATH = resourceAbsolutePath.concat("\\src\\main\\resources\\app-config.yml");
    }

    /**
     * 读取 yml 文件中内容
     *
     * @return
     */
    public static JSONObject getYml() {
        return readYmlDirect(APP_DEFAULT_CONFIG_PATH);
    }

    /**
     * 读取 yml 文件中内容
     *
     * @return
     */
    public static JSONObject getLocalYml() {
        return readYmlDirect(READ_FILE_PATH);
    }

    /**
     * 读取指定路径下 yml 文件中内容
     * @param readFilePath
     * @return
     */
    private static JSONObject readYmlDirect(String readFilePath) {
        JSONObject result = new JSONObject();
        try {
            FileInputStream fileInputStream = new FileInputStream(readFilePath);
            Yaml yaml = new Yaml();
            Object load = yaml.load(fileInputStream);
            result = JSONObject.parseObject(JSONObject.toJSONString(load));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 遍历 yml 获取配置属性的值
     *
     * @param arr
     * @return
     */
    public static Object getConfigProperties(List<String> arr) {
        JSONObject content = getYml();
        JSONObject jsonObject = new JSONObject();
        getMatchesProperties(content, arr, jsonObject);
        return jsonObject.get(RESULT);
    }

    /**
     * 遍历 yml 获取配置属性的值
     *
     * @param prefix
     * @param fieldName
     * @return
     */
    public static Object getConfigProperties(String prefix, String fieldName) {
        JSONObject content = getYml();
        return parserObject(prefix, fieldName, content);
    }

    /**
     * 遍历 yml 获取配置属性的值
     *
     * @param arr
     * @return
     */
    public static Object getLocalConfigProperties(List<String> arr) {
        JSONObject content = getLocalYml();
        JSONObject jsonObject = new JSONObject();
        getMatchesProperties(content, arr, jsonObject);
        return jsonObject.get(RESULT);
    }

    /**
     * 遍历 yml 获取配置属性的值
     *
     * @param fieldName
     * @return
     */
    public static Object getLocalConfigProperties(String prefix, String fieldName) {
        JSONObject content = getLocalYml();
        return parserObject(prefix, fieldName, content);
    }

    /**
     * 解析获取匹配的值对象
     * @param prefix
     * @param fieldName
     * @param content
     * @return
     */
    private static Object parserObject(String prefix, String fieldName, JSONObject content) {
        JSONObject jsonObject = new JSONObject();
        for (Map.Entry<String, Object> entry : content.entrySet()) {
            if (Objects.equals(prefix, entry.getKey())) {
                Object matchesValue = entry.getValue();
                if (null != matchesValue) {
                    JSONObject parseObject = JSONObject.parseObject(JSONObject.toJSONString(matchesValue));
                    for (Map.Entry<String, Object> objectEntry : parseObject.entrySet()) {
                        if (Objects.equals(fieldName, formatSeparator(objectEntry.getKey()))) {
                            jsonObject.put(RESULT, objectEntry.getValue());
                        }
                    }
                }
            }
        }
        return jsonObject.get(RESULT);
    }

    /**
     * 递归获取 yml 中对象属性
     *
     * @param matchesObj
     * @param list
     * @return
     */
    private static void getMatchesProperties(Object matchesObj, List<String> list, JSONObject jsonObject) {
        JSONObject matchesRes = JSONObject.parseObject(JSONObject.toJSONString(matchesObj));
        Object result = matchesRes.get(list.get(0));
        jsonObject.put(RESULT, result);
        list = list.subList(1, list.size());
        if (null != result && list.size() > 0) {
            getMatchesProperties(result, list, jsonObject);
        }
    }

}

